package com.app.island.cash.wegit

import android.animation.ValueAnimator
import android.content.Context
import android.graphics.*
import android.graphics.drawable.Drawable
import android.text.InputType
import android.text.TextUtils
import android.util.AttributeSet
import android.view.*
import android.view.animation.Animation
import android.view.animation.CycleInterpolator
import android.view.animation.TranslateAnimation
import android.view.inputmethod.InputMethodManager
import androidx.appcompat.widget.AppCompatEditText
import androidx.core.content.ContextCompat
import androidx.core.graphics.drawable.DrawableCompat
import com.app.island.cash.R

/**
 * Author: TinhoXu
 * E-mail: xth@duandai.com
 * Date: 2017/12/15 17:10
 *
 *
 * Description:
 */
open class ClearEditText : AppCompatEditText {
    // 按钮资源
    private val CLEAR = R.drawable.edt_clear

    // 动画时长
    protected val ANIMATOR_TIME = 200

    // ----------------以下方法为方便子类继承，只使用ClearEditText就没有用处---------------------------------------------------------------------
    // 按钮左右间隔,单位PX
    var interval = 0
        private set

    // 清除按钮宽度,单位PX
    var widthClear = 0
        private set

    // 左内边距
    private var mPaddingLeft = 0

    // 右内边距
    private var mPaddingRight = 0

    // 右侧多出的空间(间隔 + 按钮宽度)
    private var mExtraWidth = 0

    // 清除按钮的bitmap
    var bitmapClear: Bitmap? = null
        private set

    // 清除按钮出现动画
    private var mAnimatorVisible: ValueAnimator? = null

    // 消失动画
    private var mAnimatorGone: ValueAnimator? = null

    // 是否显示的记录
    private var isVisible = false

    // 右边添加其他按钮时使用
    private var mRight = 0
    private var drawFilter: PaintFlagsDrawFilter? = null
    protected var inputMethodManager: InputMethodManager? = null

    constructor(context: Context) : super(context) {
        init(context)
    }

    constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) {
        init(context)
    }

    constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(
        context,
        attrs,
        defStyleAttr
    ) {
        init(context)
    }

    private fun init(context: Context) {
        // 获得清除图片的Bitmap对象
        bitmapClear = createBitmap(CLEAR, context)
        interval = context.resources.getDimension(R.dimen.dp_5).toInt()
        widthClear = context.resources.getDimension(R.dimen.dp_15).toInt()
        mPaddingLeft = paddingLeft
        mPaddingRight = paddingRight
        mExtraWidth = interval + widthClear + interval
        mAnimatorVisible = ValueAnimator.ofFloat(0f, 1f).setDuration(ANIMATOR_TIME.toLong())
        mAnimatorGone = ValueAnimator.ofFloat(1f, 0f).setDuration(ANIMATOR_TIME.toLong())
        drawFilter = PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG or Paint.FILTER_BITMAP_FLAG)
        inputMethodManager =
            getContext().getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
        // 屏蔽EditText的复制、粘贴功能
        customSelectionActionModeCallback = object : ActionMode.Callback {
            override fun onCreateActionMode(mode: ActionMode, menu: Menu): Boolean {
                return false
            }

            override fun onPrepareActionMode(mode: ActionMode, menu: Menu): Boolean {
                return false
            }

            override fun onActionItemClicked(mode: ActionMode, item: MenuItem): Boolean {
                return false
            }

            override fun onDestroyActionMode(mode: ActionMode) {}
        }
        isLongClickable = false
        setTextIsSelectable(false)
    }

    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)
        // 抗锯齿
        canvas.drawFilter = drawFilter
        if (mAnimatorVisible!!.isRunning) {
            val scale = mAnimatorGone!!.animatedValue as Float
            drawClear(scale, canvas)
            invalidate()
        } else if (isVisible) {
            drawClear(1f, canvas)
        }
        if (mAnimatorGone!!.isRunning) {
            val scale = mAnimatorGone!!.animatedValue as Float
            drawClear(scale, canvas)
            invalidate()
        }
    }

    /**
     * 绘制清除按钮的图案
     *
     * @param scale 缩放比例
     */
    protected fun drawClear(scale: Float, canvas: Canvas) {
        val right =
            (width + scrollX - mPaddingRight - interval - mRight - widthClear * (1f - scale) / 2f).toInt()
        val left =
            (width + scrollX - mPaddingRight - interval - mRight - widthClear * (scale + (1f - scale) / 2f)).toInt()
        val top = ((height - widthClear * scale) / 2).toInt()
        val bottom = (top + widthClear * scale).toInt()
        val rect = Rect(left, top, right, bottom)
        canvas.drawBitmap(bitmapClear!!, null, rect, null)
    }

    /**
     * EditText内容变化的监听
     */
    override fun onTextChanged(
        text: CharSequence,
        start: Int,
        lengthBefore: Int,
        lengthAfter: Int
    ) {
        if (inputType == InputType.TYPE_NUMBER_FLAG_DECIMAL or InputType.TYPE_CLASS_NUMBER && !TextUtils.isEmpty(
                text
            ) && text[0] == '.'
        ) {
            if (text.length == 1) {
                setText("0.")
            } else {
                setText(getText()!!.replace(0, 0, "0."))
            }
            setSelection(getText()!!.length)
        }
        super.onTextChanged(text, start, lengthBefore, lengthAfter)
        if (text.length > 0 && isFocused && isEditThis) {
            if (!isVisible) {
                isVisible = true
                startVisibleAnimator()
            }
        } else {
            if (isVisible) {
                isVisible = false
                startGoneAnimator()
            }
        }
    }

    /**
     * 焦点变更
     */
    override fun onFocusChanged(focused: Boolean, direction: Int, previouslyFocusedRect: Rect?) {
        super.onFocusChanged(focused, direction, previouslyFocusedRect)
        // 无焦点，则永不显示清除按钮
        if (focused && !TextUtils.isEmpty(text) && isEditThis) {
            if (!isVisible) {
                isVisible = true
                startVisibleAnimator()
            }
        } else {
            if (isVisible) {
                isVisible = false
                startGoneAnimator()
            }
        }
    }

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec)
        var additional = 0
        if (gravity == Gravity.CENTER || gravity == Gravity.CENTER_HORIZONTAL) {
            additional = mExtraWidth + mRight + mPaddingRight
        }
        // 设置内边距
        setPadding(
            mPaddingLeft + additional,
            paddingTop,
            mExtraWidth + mRight + mPaddingRight,
            paddingBottom
        )
        if (!TextUtils.isEmpty(text) && isEditThis) {
            if (!isVisible) {
                isVisible = true
                startVisibleAnimator()
            }
        } else {
            if (isVisible) {
                isVisible = false
                startGoneAnimator()
            }
        }
    }

    /**
     * 触控执行的监听
     */
    override fun onTouchEvent(event: MotionEvent): Boolean {
        if (event.action == MotionEvent.ACTION_UP) {
            val touchable = (width - mPaddingRight - interval - mRight - widthClear < event.x
                    && event.x < width - mPaddingRight - interval - mRight)
            if (touchable && isVisible) {
                error = null
                this.setText("")
            }
        }
        return super.onTouchEvent(event)
    }

    /**
     * 是否在编辑当前view
     */
    protected val isEditThis: Boolean
        protected get() = isKeyboardShown(rootView) && inputMethodManager!!.isActive(this)

    /**
     * 软键盘是否显示
     */
    private fun isKeyboardShown(rootView: View): Boolean {
        val softKeyboardHeight = 100
        val rect = Rect()
        rootView.getWindowVisibleDisplayFrame(rect)
        val dm = rootView.resources.displayMetrics
        val heightDiff = rootView.bottom - rect.bottom
        return heightDiff > softKeyboardHeight * dm.density
    }

    /**
     * 开始清除按钮的显示动画
     */
    private fun startVisibleAnimator() {
        endAnimator()
        mAnimatorVisible!!.start()
        invalidate()
    }

    /**
     * 开始清除按钮的消失动画
     */
    private fun startGoneAnimator() {
        endAnimator()
        mAnimatorGone!!.start()
        invalidate()
    }

    /**
     * 结束所有动画
     */
    private fun endAnimator() {
        mAnimatorGone!!.end()
        mAnimatorVisible!!.end()
    }

    /**
     * 开始晃动动画
     */
    fun startShakeAnimation() {
        if (animation == null) {
            this.animation = shakeAnimation(4)
        }
        startAnimation(animation)
    }

    /**
     * 晃动动画
     *
     * @param counts 0.5秒钟晃动多少下
     */
    private fun shakeAnimation(counts: Int): Animation {
        val translateAnimation: Animation = TranslateAnimation(0F, 10F, 0F, 0F)
        translateAnimation.interpolator = CycleInterpolator(counts.toFloat())
        translateAnimation.duration = 500
        return translateAnimation
    }

    fun createBitmap(resources: Int, context: Context?): Bitmap {
        val drawable = ContextCompat.getDrawable(
            context!!, resources
        )
        val wrappedDrawable = DrawableCompat.wrap(
            drawable!!
        )
        //        DrawableCompat.setTint(wrappedDrawable, getCurrentHintTextColor()); // 给图标染上当前提示文本的颜色并且转出Bitmap
        return drawableToBitmap(wrappedDrawable)
    }

    /**
     * drawable转换成bitmap
     */
    private fun drawableToBitmap(drawable: Drawable): Bitmap {
        val w = drawable.minimumWidth
        val h = drawable.minimumHeight
        val config =
            if (drawable.opacity != PixelFormat.OPAQUE) Bitmap.Config.ARGB_8888 else Bitmap.Config.RGB_565
        val bitmap = Bitmap.createBitmap(w, h, config)
        val canvas = Canvas(bitmap)
        drawable.setBounds(0, 0, w, h)
        drawable.draw(canvas)
        return bitmap
    }

    fun dp2px(dipValue: Float): Int {
        val scale = resources.displayMetrics.density
        return (dipValue * scale + 0.5f).toInt()
    }

    fun getmPaddingRight(): Int {
        return mPaddingRight
    }

    fun addRight(right: Int) {
        mRight += right
    }
}